/**
 * Copyright 2009 Joe LaPenna
 */

package com.googlecode.dumpcatcher.logging;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Arrays;

import junit.framework.TestCase;

/**
 * @author Joe LaPenna (joe@joelapenna.com)
 */
public class DumpcatcherTestCase extends TestCase {

    private static final String PRODUCT_KEY = "agtkdW1wY2F0Y2hlcnINCxIHUHJvZHVjdBgCDA";
    private static final String SECRET = "4ceafc4082e345ec98972c00f035609b";
    private static final String CLIENT = "unittest";

    private static final String EXPECTED_HMAC_DIGEST = "9d98bc4bf11cc77c22319607ad90f5beeab1938a";
    private static final String SHORT_STRING = "SomeCrashMannnnn: New Line with = sign";
    private static final String LONG_STRING = "Long string goes here.\nNew Line with = sign";

    private Dumpcatcher mDumpCatcher;

    public void setUp() {
        mDumpCatcher = new Dumpcatcher(PRODUCT_KEY, SECRET, "http://localhost:8080/add", CLIENT, 2);
    }

    public void test_sendCrash() throws IOException {
        HttpResponse response = mDumpCatcher.sendCrash( //
                new BasicNameValuePair("short", SHORT_STRING), //
                new BasicNameValuePair("long", LONG_STRING));
        assertNotNull(response);
        assertEquals(200, response.getStatusLine().getStatusCode());
        response.getEntity().consumeContent();
    }

    public void testMany_sendCrash() throws IOException {
        for (int i = 0; i < 50; i++) {
            test_sendCrash();
        }
    }

    public void test_sendCrashCredentialsInvalidSecret() throws IOException {
        Dumpcatcher dc = new Dumpcatcher(PRODUCT_KEY, "invalid", "http://localhost:8080/add",
                CLIENT, 2);

        HttpResponse response = dc.sendCrash( //
                new BasicNameValuePair("short", SHORT_STRING), new BasicNameValuePair("long",
                        LONG_STRING));
        assertNotNull(response);
        assertEquals(401, response.getStatusLine().getStatusCode());
        response.getEntity().consumeContent();
    }

    public void test_addExtraQueryPairsAndSign() throws SignatureException {
        NameValuePair[] parameters = {
                new BasicNameValuePair("short", SHORT_STRING),
                new BasicNameValuePair("long", LONG_STRING)
        };
        ArrayList<NameValuePair> pairs = mDumpCatcher.addExtraQueryPairsAndSign(parameters);

        String foundHmac = null;
        String foundProductKey = null;
        String foundClient = null;
        NameValuePair pair;
        for (int i = 0; i < pairs.size(); i++) {
            pair = pairs.get(i);
            if (pair.getName().equals("hmac")) {
                foundHmac = pair.getValue();
            } else if (pair.getName().equals("product_key")) {
                foundProductKey = pair.getValue();
            } else if (pair.getName().equals("client")) {
                foundClient = pair.getValue();
            }
        }

        assertEquals("Expecting", EXPECTED_HMAC_DIGEST, foundHmac);
        assertEquals("Expecting", PRODUCT_KEY, foundProductKey);
        assertEquals("Expecting", CLIENT, foundClient);
    }

    public void test_calculateHmac() throws SignatureException {
        NameValuePair[] pairs = {
                new BasicNameValuePair("client", CLIENT),
                new BasicNameValuePair("long", LONG_STRING),
                new BasicNameValuePair("product_key", PRODUCT_KEY),
                new BasicNameValuePair("short", SHORT_STRING),
        };
        assertEquals("Expecting", //
                EXPECTED_HMAC_DIGEST, //
                mDumpCatcher.calculateHMAC(Arrays.asList(pairs)));
    }

    public void test_calculateRFC2104HMAC() throws SignatureException {
        StringBuffer sb = new StringBuffer();
        sb.append("client=" + CLIENT);
        sb.append("&long=" + LONG_STRING);
        sb.append("&product_key=" + PRODUCT_KEY);
        sb.append("&short=" + SHORT_STRING);

        assertEquals("Expecting", //
                EXPECTED_HMAC_DIGEST, //
                mDumpCatcher.calculateRFC2104HMAC(sb.toString(), SECRET));
    }
}
